package com.note.user.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.note.user.dto.UserDto;
import org.springframework.util.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

/**
 * @Package：com.note.user.util
 * @Name：JwtUtil
 * @Author：热伊木
 * @Email：uyevan@163.com
 * @Date：2023-12-12-15:52
 * @Description：Jwt令牌授权工具类
 */
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
public class JwtUtil {
    /*过期时间（默认7天）*/
    private static final int EXPIRATION_TIME = 60 * 60 * 24 * 7;
    /*签名密钥*/
    private static final String SECRET = "wownote!E@W#A$N";
    /*令牌前缀*/
    public static final String TOKEN_PREFIX = "Bearer ";
    /*表头授权*/
    public static final String AUTHORIZATION = "Authorization";
    private static final long LONG = 1000L;

    /**
     * 生成token
     *
     * @param userDto 用户数据模型
     * @return
     */
    public static String generateToken(UserDto userDto) {
        JWTCreator.Builder builder = JWT.create();
        Calendar calendar = Calendar.getInstance();
        Date time = calendar.getTime();
        //设置授权时间
        calendar.setTime(time);
        //设置过期时间
        calendar.add(Calendar.SECOND, EXPIRATION_TIME);
        //定义hash数据项
        HashMap<String, String> map = new HashMap<>();
        map.put("username", userDto.getUsername());
        map.put("password", userDto.getPassword()/*已MD5加密*/);
        //payload 将用户信息放到令牌里面
        map.forEach(builder::withClaim);
        builder.withExpiresAt(calendar.getTime());//指定令牌的过期时间
        Algorithm algorithm = Algorithm.HMAC256(SECRET);//密钥
        return String.format("%s%s", TOKEN_PREFIX, builder.sign(algorithm));//签名
    }

    /**
     * 验证token
     *
     * @param token 用户传来的令牌
     */
    public static DecodedJWT verify(String token) {
        //如果有任何异常会在此处报异常
        Algorithm algorithm = Algorithm.HMAC256(SECRET);//密钥
        String newToken = token.replace(TOKEN_PREFIX, "");
        JWTVerifier jwtVerifier = JWT.require(algorithm).build();
        return jwtVerifier.verify(newToken);
    }

    /**
     * 获取payload自定义参数
     *
     * @param token
     * @param key
     * @return
     */
    public static String getPayload(String token, String key) {
        DecodedJWT decodedJWT = verify(token);
        return decodedJWT.getClaim(key).asString();
    }

    /**
     * 获取令牌过期时间
     *
     * @param token 令牌
     * @return 10位时间戳
     */
    public static long getExpiresAt(String token) {
        String newToken = token.replace(TOKEN_PREFIX, "");
        DecodedJWT decodedJWT = JWT.decode(newToken);
        return decodedJWT.getExpiresAt().getTime() / LONG;
    }

    // 获取Bearer令牌的载荷部分--->异常不报错
    /**
     * 获取载荷部分中的json
     *
     * @param token
     * @return
     */
    public static String getPayloadFromToken(String token, String key) {
        String[] parts = token.split("\\.");/*转数组*/
        String baseDecodeData = Base64.decodeStr(parts[1]);/*截取载荷部分*/
        return StringUtils.hasLength(JSONUtil.parseObj(baseDecodeData).getStr(key)) ?
                JSONUtil.parseObj(baseDecodeData).getStr(key) : "";
    }
}
